在過去 JS 要處理 Ajax 這個非同步語法,會很容易用到 Callback 寫法,而 Callback 不但不好管理,還容易寫成 Callback Hell,如圖:
幸好 ES6 新增了  Promise  ,對於 JS 這個單執行序的語言 Promise 非常實用。
Promise 直接翻譯成中文會是承諾 ,而 Promise 的使用結果也就分成兩種
resolve()
reject()
而要使用 Promise  大致上分為兩個步驟:
new Promise() 的函式建構式創造一個新的 Promise 物件Promise 物件在創造函式建構式時,函式建構式會帶上兩個參數 resolve 、 reject , 第一個參數是用來執行 成功的方法,第二個則是 失敗的方法,這兩個參數名稱接可以自定義,不過實際開發時多數,仍會使用這個名稱做命名。
(這邊是把 Promise 寫成函式方法,因此可以帶入參數,在透過參數來做判斷。)
function PromiseFn(String) {
	// 創造建構函式並帶上 resolve 、 reject 參數
  return new Promise((resolve, reject) => {
    setTimeout(function () {
        // Promise 承諾的判斷
      if (String.length >= 5) {
        resolve(`Promise 成功, ${ String } 共 ${ String.length } 個字 `)
      } else {
        reject('Promise 失敗')
      }
    }, 2000);
  });
}
建立好 Promise 函式建構式後,便是執行 Promise  本身了,接者執行 Promise 本身時,我們可以使用 then() 、 catch()  他們會分別接收 Promise  成功 以及 Promise 失敗的結果,但他們需要寫上一個 Callback Function ,若要顯示 Promise 建構式中的  resolve() 、 reject()  設定的資料,那麼會需要在  Callback Function 中帶上一個參數,這些參數就會顯示 resolve() 、 reject()  設定的資料:
function PromiseFn(String) {
  return new Promise((resolve, reject) => {
    setTimeout(function () {
      if (String.length >= 5) {
        resolve(`Promise 成功, ${ String } 共 ${ String.length } 個字 `)
      } else {
        reject('Promise 失敗')
      }
    }, 2000);
  });
}
PromiseFn('test')// Promise 失敗
.then((res)=>{ // 第一個參數會回傳 resolve() 設定資料
  console.log(res)  
})
.catch((err)=>{
  console.log(err) // 第一個參數會回傳 reject() 設定資料
})
PromiseFn('Ryder') //Promise 成功, Ryder 共 5 個字
.then((res)=>{
  console.log(res)
})
.catch((err)=>{
  console.log(err)
})
扣除上面的 Promise 基本方法,Promise  還提供 Promise.all()  、 Promise.race()  兩種用法。
Promise.all()  時,會執行 Promise.all() 中所有的 Promise 方法,並將回傳一個陣列,而這個陣列就是 resolve()  所提供的。function PromiseFn(String) {
  return new Promise((resolve, reject) => {
    setTimeout(function () {
      if (String.length >= 5) {
        resolve(`Promise 成功, ${ String } 共 ${ String.length } 個字 `)
      } else {
        reject('Promise 失敗')
      }
    }, 2000);
  });
}
Promise.all([PromiseFn('Ryder'), PromiseFn('youtube')]).then((res)=>{
	console.log(res) //['Promise 成功, Ryder 共 5 個字 ', 'Promise 成功, youtube 共 7 個字 ']
})
Promise.race() 和 Promise.all()  一樣,會同時執行 Promise.race()  中所有 Promise 方法,但他只會回傳最快執行完畢的 Promise 方法。const p = new Promise((resolve) => {
  if (true) {
    resolve(`直接執行 Promise`)
  }
})
function PromiseFn(String) {
  return new Promise((resolve, reject) => {
    setTimeout(function () {
      if (String.length >= 5) {
        resolve(`Promise 成功, ${String} 共 ${String.length} 個字 `)
      } else {
        reject('Promise 失敗')
      }
    }, 2000);
  });
}
Promise.race([PromiseFn('Ryder'), p]).then((res) => {
  console.log(res) //直接執行 Promise
})
上面介紹的 Promise.all()   Promise.race() 都是會同時執行的方法,不過我們肯定會遇到需要依序執行 Promise 的狀況,在過去使用 Callback Function 時就會寫出超巢的 Callback Hell,不過 Promise 則提供了鏈式寫法,可以輕鬆的達成需求。
要使用  Promise  的鏈式寫法,只需要在 then()  中使用 return  並呼叫下一個 Promise  這樣變能使用 .then() 不斷串聯下去。
const p = new Promise((resolve) => {
  if (true) {
    resolve(`直接執行 Promise`)
  }
})
function PromiseFn(String) {
  return new Promise((resolve, reject) => {
    setTimeout(function () {
      if (String.length >= 5) {
        resolve(`Promise 成功, ${String} 共 ${String.length} 個字 `)
      } else {
        reject('Promise 失敗')
      }
    }, 2000);
  });
}
PromiseFn('Ryder')
  .then((res) => {
    console.log(res) // Promise 成功, Ryder 共 5 個字
    return PromiseFn('youtube') // Promise 鏈式寫法,可以不斷寫 Promise 下去。
  }).then((res) => {
    console.log(res)  // Promise 成功, youtube 共 7 個字 
    return p
  }).then((res) => {
    console.log(res) // 直接執行 Promise
  })